package imagedemo;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import javax.imageio.ImageIO;
import javax.swing.Spring;

import org.junit.Test;

public class ImageHandler {
	//系统文件路径符
	private String fSeq=File.separator;
	
	/**
	 * 将指定颜色组合转换为RGB
	 * @param alpha
	 * @param red
	 * @param green
	 * @param blue
	 * @return
	 */
	private int colorToRGB(int alpha,int red,int green,int blue){
		int newPixel = 0;
		newPixel += alpha;
		newPixel = newPixel<<8;
		newPixel += red;
		newPixel = newPixel<<8;
		newPixel += green;
		newPixel = newPixel<<8;
		newPixel += blue;
		return newPixel;
	}
	
	/**
	 * 获取灰度化图像
	 * @param buffImg
	 * @return
	 */
	private BufferedImage getGrayImg(BufferedImage buffImg){
			int height = buffImg.getHeight();
			int width = buffImg.getWidth();
		//新建一个灰度化bufferImage
		BufferedImage newBuffImg = new BufferedImage(width, height, buffImg.getType());
		//读取像素点
		for(int i=0;i<width;i++){
			for(int j=0;j<height;j++){
				final int rgb = buffImg.getRGB(i, j);
				final int r = (rgb >> 16) & 0xff;
				final int g = (rgb >> 8) & 0xff;
				final int b = rgb & 0xff;
				int gray = (int) (0.3*r + 0.59*g + 0.11*b);
				int newPixel = colorToRGB(255, gray, gray, gray);
				newBuffImg.setRGB(i, j, newPixel);
			}
		}
		return newBuffImg;
	}
	
	/**
	 * 迭代获取图片的最佳阈值
	 * @param 
	 * @return
	 */
	private int getBestThreshold(BufferedImage buffImg){
		//图片宽度
		int gWidth = buffImg.getWidth();
		//图片高度
		int gHeight = buffImg.getHeight();
		//灰度值数组
		int[] gray=new int[gWidth*gHeight];
		int num=0;
		for(int i=0;i<gWidth;i++){
			for(int j=0;j<gHeight;j++){
				final int rgb = buffImg.getRGB(i, j);
				final int r = (rgb >> 16) & 0xff;
				final int g = (rgb >> 8) & 0xff;
				final int b = rgb & 0xff;
				int grayRGB = (int) (0.3*r + 0.59*g + 0.11*b);
				gray[num]=grayRGB;
				num++;
			}
		}
		//gMax最大灰度值，gMin最小灰度值
		int gMax=gray[0];
		int gMin=gray[0];
		for(int index=0;index<gWidth*gHeight;index++){
			int grayValue = gray[index];
			if(gMin>grayValue){
				gMin=grayValue;
			}
			if(gMax<grayValue){
				gMax=grayValue;
			}
		}
		
		//获取灰度直方图
		int[] histogram = new int[256];
		for(int t=gMin;t<gMax;t++){
			for(int k=0;k<gHeight*gWidth;k++){
				if(gray[k] == t){
					histogram[t]++;
				}
			}
		}
		
		int count1=0,count2=0;//灰度像素点的总个数
		int sum1=0,sum2=0;//总的灰度值
		int bp,fp;
		int T=0;//阈值
		int newT=(gMin+gMax)/2;//初始阈值
		while(T!=newT){
			int i=0;
			//求出背景和前景的平均灰度值
			for(;i<T;i++){
				count1+=histogram[i];
				sum1+=histogram[i]*i;
			}
			
			bp=(count1==0)?0:(sum1/count1);//背景的平均灰度值
			
			for(int j=i;j<histogram.length;j++){
				count2+=histogram[j];
				sum2+=histogram[j]*j;
			}
			
			fp=(count2==0)?0:(sum2/count2);//前景的平局灰度值
			T=newT;
			newT=(bp+fp)/2;
		}
		
		return newT;
	}

	/**
	 * 将指定图片进行灰化，并以gray_为前缀保存
	 * 灰化方法采用权重法进行灰化
	 * @param imgPath ： 图片路径
	 * @throws IOException
	 */
	public void turnGray(String imgPath) throws IOException{
		
		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		//获取灰度化图片
		BufferedImage newBuffImg = getGrayImg(buffImg);
		//将灰度化图片写出
		int lastIndexOf = imgPath.lastIndexOf(fSeq);
		String filePath = imgPath.substring(0, lastIndexOf);
		String nfileName = "gray_"+imgPath.substring(lastIndexOf+1);
		File newFile = new File(filePath+fSeq+nfileName);
		String remoteName=imgPath.substring(imgPath.lastIndexOf(".")+1);
		if(newFile.exists()){
			newFile.createNewFile();
		}
		ImageIO.write(newBuffImg, remoteName, newFile);
	}
	/**
	 * 将指定图片进行二值化，并以binary_为前缀进行保存
	 * @param imgPath ： 图片路径
	 * @throws IOException
	 */
	public void turnBinary(String imgPath) throws IOException{
			
		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		
		int width = buffImg.getWidth();
		int height = buffImg.getHeight();
		//黑色的rgb值
		int blackRGB=Color.BLACK.getRGB();
		//白色的rgb值
		int whiteRGB=Color.white.getRGB();
		
		//新建一个bufferImage
		BufferedImage newBuffImg = new BufferedImage(width, height, buffImg.getType());
		int bestThreshold = getBestThreshold(buffImg);
		//读取像素点
		for(int i=0;i<width;i++){
			for(int j=0;j<height;j++){
				int rgb2 = colorToRGB(255, bestThreshold, bestThreshold, bestThreshold);
				int rgb = buffImg.getRGB(i, j);
				if(rgb>rgb2){
					newBuffImg.setRGB(i, j, whiteRGB);
				}else{
					newBuffImg.setRGB(i, j, blackRGB);
				}
			}
		}
		int lastIndexOf = imgPath.lastIndexOf(fSeq);
		String filePath = imgPath.substring(0, lastIndexOf);
		String nfileName = "binary_"+imgPath.substring(lastIndexOf+1);
		File newFile = new File(filePath+fSeq+nfileName);
		String remoteName=imgPath.substring(imgPath.lastIndexOf(".")+1);
		if(newFile.exists()){
			newFile.createNewFile();
		}
		ImageIO.write(newBuffImg, remoteName, newFile);
	}
	
	/**
	 * 统计各个像素点出现的次数
	 * @param bufferedImage
	 * @return 
	 */
	public HashMap<Integer, Integer> getCountByRgb(BufferedImage bufferedImage){
		int width = bufferedImage.getWidth();
		int height = bufferedImage.getHeight();
		
		//统计各个像素点出现的次数
		HashMap<Integer,Integer> hashMap = new HashMap<Integer, Integer>();
		for (int i = 0; i < width; i++) {
			for(int j=0;j < height; j++){
				int rgb = bufferedImage.getRGB(i, j);
				if(hashMap.get(rgb)!=null){
					Integer integer = hashMap.get(rgb);
					hashMap.put(rgb, integer+1);
				}else{
					hashMap.put(rgb, 1);
				}
			}
		}
		//统计结束
		return hashMap;
	}
	
	/**
	 * 获取出现最多的像素点
	 * @param hashMap
	 * @return
	 */
	public Entry<Integer, Integer> getMaxCoutByRgb(HashMap<Integer,Integer> hashMap){
		Iterator<Entry<Integer, Integer>> iterator = hashMap.entrySet().iterator();
		Entry<Integer, Integer> maxEntry=null;
		//获取出现最多的像素点
		while(iterator.hasNext()){
			Entry<Integer, Integer> entry = iterator.next();
			if(maxEntry==null){
				maxEntry=entry;
			}
			if(maxEntry!=null&&entry.getValue()>maxEntry.getValue()){
				maxEntry=entry;
			}
		}
		//获取结束
		return maxEntry;
	}
	
	/**
	 * 统计图像像素点的平均值
	 * @param imgPath
	 * @return 像素点的平均值
	 * @throws IOException 
	 */
	public int getAverageByRgb(String imgPath) throws IOException{
		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		
		int width = buffImg.getWidth();
		int height = buffImg.getHeight();
		BigInteger sumRgb = BigInteger.ZERO;
		
		//总的像素值
		for (int i = 0; i < width; i++) {
			for(int j=0;j < height; j++){
				int rgb = buffImg.getRGB(i, j);
				sumRgb = sumRgb.add(new BigInteger(rgb+""));
			}
		}
		//统计结束
		return (sumRgb.divide(new BigInteger((width*height)+""))).intValue();
	}
	
	/**
	 * 统计现在非白色的平均值
	 * @param imgPath
	 * @return
	 * @throws IOException
	 */
	public int getAverageRgbNoWhite(String imgPath) throws IOException{
		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		
		int width = buffImg.getWidth();
		int height = buffImg.getHeight();
		//非白色的像素值
		int sumNoWhite=0;
		
		BigInteger sumRgb = BigInteger.ZERO;
		
		//非白色的总的像素值
		for (int i = 0; i < width; i++) {
			for(int j=0;j < height; j++){
				int rgb = buffImg.getRGB(i, j);
				if(rgb!=-1){
					sumRgb = sumRgb.add(new BigInteger(rgb+""));
					sumNoWhite++;
				}
			}
		}
		//统计结束
		return (sumRgb.divide(new BigInteger(sumNoWhite+""))).intValue();
	}
	
	/**
	 * 淡化指定范围值内的像素点，并生成re_为前缀的jpg文件
	 * @param imgPath
	 * @param maxValue
	 * @param minValue
	 * @throws IOException
	 */
	public void removeRgbRange(String imgPath,int maxValue,int minValue) throws IOException{

		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		
		int width = buffImg.getWidth();
		int height = buffImg.getHeight();
		
		//新建一个bufferImage
		BufferedImage newBuffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//读取像素点
		for(int i=0;i<width;i++){
			for(int j=0;j<height;j++){
				int rgb = buffImg.getRGB(i, j);
				if(rgb<maxValue&&rgb>minValue){
					newBuffImg.setRGB(i, j, new Color(255, 255, 255).getRGB());
				}else{
					newBuffImg.setRGB(i, j, rgb);
				}
			}
		}
		int lastIndexOf = imgPath.lastIndexOf(File.separator);
		String filePath = imgPath.substring(0, lastIndexOf);
		String nfileName = "re_"+imgPath.substring(lastIndexOf+1);
		File newFile = new File(filePath+File.separator+nfileName);
		String remoteName=imgPath.substring(imgPath.lastIndexOf(".")+1);
		if(newFile.exists()){
			newFile.createNewFile();
		}
		ImageIO.write(newBuffImg, remoteName, newFile);
	}
	
	/**
	 * 深化指定范围内的像素点
	 * @param imgPath
	 * @param maxValue
	 * @param minValue
	 * @throws IOException
	 */
	public void deepenRgbRange(String imgPath,int maxValue,int minValue) throws IOException{

		File file = new File(imgPath);
		BufferedImage buffImg = ImageIO.read(file);
		
		int width = buffImg.getWidth();
		int height = buffImg.getHeight();
		//获取黑色的rgb得int值
		int black=new Color(0, 0, 0).getRGB();
		//新建一个bufferImage
		BufferedImage newBuffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//读取像素点
		for(int i=0;i<width;i++){
			for(int j=0;j<height;j++){
				int rgb = buffImg.getRGB(i, j);
				if(rgb<maxValue&&rgb>minValue){
					newBuffImg.setRGB(i, j, black);
				}else{
					newBuffImg.setRGB(i, j, rgb);
				}
			}
		}
		int lastIndexOf = imgPath.lastIndexOf(File.separator);
		String filePath = imgPath.substring(0, lastIndexOf);
		String nfileName = "deepen_"+imgPath.substring(lastIndexOf+1);
		File newFile = new File(filePath+File.separator+nfileName);
		String remoteName=imgPath.substring(imgPath.lastIndexOf(".")+1);
		if(newFile.exists()){
			newFile.createNewFile();
		}
		ImageIO.write(newBuffImg, remoteName, newFile);
	}
	
}
